<!--
 * @Author: xiaotiwen
 * @Date: 2020-05-20 16:12:38
 * @LastEditTime: 2020-07-22 16:52:03
 * @LastEditors: xiaotiwen
 * @FilePath: \eduweb\src\views\practiceManagement\scheduleSetting\ArrangePanel.vue
 * @Description:排课面板
-->
<template>
    <div class="arrange-panel">
        <div v-show="page=='arrange'">
            <el-container>
                <el-header class="arrange-panel-header" height="85px">
                    <div class="class-profiles">
                        <div class="head-text">{{`${classData.courseName}(${classData.code})`}}</div>
                        <div class="secondary-text inline-hidden" :title="classProfiles">{{classProfiles}}</div>
                        <!-- <div class="secondary-text inline-hidden" :title="classData.compuss">{{classData.compuss}}</div> -->
                    </div>
                    <div class="period">
                        <div class="head-text">{{$t('arrangement.weekHour')}}</div>
                        <div class="number">{{weekHours}}</div>
                    </div>
                    <div class="period">
                        <div class="head-text">{{$t('arrangement.totalHour')}}</div>
                        <div class="number">{{period}}</div>
                    </div>
                    <div class="period" :title="$t('arrangement.preiodError')+': '+periodError">
                        <div class="head-text">{{$t('arrangement.arrangedHour')}}</div>
                        <div class="number" :style="{color: Math.abs(arrangedPeriod-period)>periodError?'#F56C6C':'#67C23A'}">{{arrangedPeriod}}</div>
                    </div>
                    <!-- <el-button class="float-right" @click="back">{{$t('common.btn.back')}}</el-button> -->
                </el-header>
                <div>
                    <div class="edu-opertion-bar" v-if="detailsFlag">
                        <div class="arrange-tips" style="position:relative">
                            <div class="inline-hidden" style="margin-right:200px;height:30px;">
                                <!-- <span>教学班名称 :
                                <el-input class="input-center" readonly size="mini"
                                    v-model="classData.name" style="width:150px;" >
                                    <template slot="append">班</template>
                                </el-input>
                                </span>-->
                                <div style="padding-top:5px;">
                                    <el-radio v-model="selectSpan" :label="1">{{$t('scheduleSetting.label.selectSpan1')}}</el-radio>
                                    <el-radio v-model="selectSpan" :label="2">{{$t('scheduleSetting.label.selectSpan2')}}</el-radio>
                                    <el-radio v-model="selectSpan" :label="3">{{$t('scheduleSetting.label.selectSpan3')}}</el-radio>
                                    <el-radio v-model="selectSpan" :label="4">{{$t('scheduleSetting.label.selectSpan4')}}</el-radio>
                                    <!-- <el-radio v-model="selectSpan" :label="6">六节</el-radio>
                                    <el-radio v-model="selectSpan" :label="8">八节</el-radio> -->
                                </div>
                                <!-- <span style="color:#aaa;font-size:12px;"
                                :title="$t('arrangement.leftSelect')">{{$t('arrangement.leftSelect')}}</span>-->
                            </div>
                            <div style="position:absolute;right:0;top:0;">
                                <!-- 教室设置弹框 -->
                                <span style="position:relative;" v-show="showRoomTable">
                                    <div class="popover">
                                        <div class="arrange-tips" style="margin:10px auto 6px">
                                            <span style="font-size:16px;">{{dayTimeString}}</span>
                                            <!-- 教学周 -->
                                            <span> {{$t('arrangement.week')}}:
                                                <el-select v-model="weekStart" size="mini" style="width: 55px;" @change="selectWeek">
                                                    <el-option v-for="i in availableWeeks" :key="i" :value="i">{{i}}</el-option>
                                                </el-select>-
                                                <el-select v-model="weekEnd" size="mini" style="width: 55px;" @change="selectWeek">
                                                    <el-option v-for="i in availableWeeks" :key="i" :value="i">{{i}}</el-option>
                                                </el-select>
                                            </span>
                                            <span>
                                                <span class="week-mode">
                                                    <el-radio v-model="weekMode" @change="selectWeekMode" label="0">{{$t("masterArrange.weekMode.continue")}}</el-radio>
                                                    <el-radio v-model="weekMode" @change="selectWeekMode" label="1">{{$t("masterArrange.weekMode.odd")}}</el-radio>
                                                    <el-radio v-model="weekMode" @change="selectWeekMode" label="2">{{$t("masterArrange.weekMode.even")}}</el-radio>
                                                </span>
                                            </span>
                                        </div>
                                        <table class="arrange-panel-popover-table">
                                            <tbody class="head">
                                                <tr style="background:#ffffff">
                                                    <td style="width:15px">
                                                        <el-checkbox v-model="allChecked" @change="allRoomCheck" :indeterminate="isIndeterminate"></el-checkbox>
                                                    </td>
                                                    <td style="width:30px;">{{$t('arrangement.week')}}</td>
                                                    <td v-if="!classroomDisabled">
                                                        <!-- 指定教室 -->
                                                        <ClassRoomFilter style="display:inline-block;" @change="setRoom(false)" @click="getOccupiedClassroomIds" v-model="selectRoom" :room-type="classData.roomType" :campus="classData.campus" :capacity="classData.number" :id-list="occupiedClassroomIds" :disabled="notPublicRoom" :popoverDisabled="notPublicRoom" type="arrange" tbd tbd-label="清除教室" query-type="exclude" :title="dayTimeString+' - 安排教室'"></ClassRoomFilter>
                                                    </td>
                                                    <td>
                                                        <!-- 指定教师 -->
                                                        <el-button type="text" size="mini" @click="showSelectTeacherDialog=true" :disabled="teacherDisabled">{{$t('arrangement.allocateTeacher')}}</el-button>
                                                    </td>
                                                </tr>
                                            </tbody>
                                            <tbody class="body" v-if="activeRoom&&activeRoom.length>0">
                                                <tr v-for="(item,index) in activeRoom" :key="index" :class="{'deleted':item.isDeleted}">
                                                    <td style="width:15px">
                                                        <el-checkbox v-model="checkedList[index]" @change="roomCheck(index)" :disabled="(index+1)<startInfo || (index+1)>endInfo"></el-checkbox>
                                                    </td>
                                                    <td style="width:30px;">{{item.weekNumber}}</td>
                                                    <td v-if="!classroomDisabled">
                                                        <span v-if="item.isDeleted">-</span>
                                                        <span v-else-if="notPublicRoom && item.roomId==0">
                                                            <span v-if="notPublicRoom" style="color:#aaa">{{classData.roomCategoryI18n}}</span>
                                                            {{item.roomName}}
                                                        </span>
                                                        <span v-if="notPublicRoom && !item.isDeleted">
                                                            {{classData.roomLabel}}
                                                        </span>
                                                        <span v-else-if="item.roomName">{{item.roomName}}</span>
                                                        <span v-else-if="classroomTbd" style="color:#aaa">{{$t('arrangement.roomTbd')}}</span>
                                                    </td>
                                                    <td class="teachers">
                                                        <span v-if="item.isDeleted">-</span>
                                                        <div v-else :title="item.teachers" style="height:20px;overflow:hidden;line-height:24px;padding:0 3px;">{{item.teachers}}</div>
                                                    </td>
                                                </tr>
                                            </tbody>
                                        </table>
                                        <div v-if="activeRoom&&activeRoom.length==0">
                                            <el-button type="info" plain disabled style="width:100%">{{$t('arrangement.tips.unarrange')}}</el-button>
                                        </div>
                                        <div v-if="!activeTime">
                                            <el-button type="info" plain disabled style="width:100%">{{$t('arrangement.tips.plsSelect')}}</el-button>
                                        </div>
                                    </div>
                                </span>
                                <!-- 教室设置 -->
                                <el-button :disabled="this.selected.length==0&&this.activedCell.length==0" :type="showRoomTable?'primary':''" @click="handleArrange">{{classroomDisabled?'选教师':'教室设置'}}</el-button>
                                <!-- 清除 -->
                                <el-button type @click="unarrange" :disabled="!this.activeTime||(activeRoom&&activeRoom.length==0)">{{$t('message.clear')}}</el-button>
                                <!-- 更换教师 -->
                                <el-button v-if="teacherSwap" size="mini" @click="emitSwapteacher(true)">{{$t('arrangement.swapTeacher')}}</el-button>
                                <!-- <el-button v-if="teacherSwap" size="mini" @click="showSwapTeacherDialog=true">
                                {{$t('arrangement.swapTeacher')}}</el-button> 弃用老的更换教师-->
                            </div>
                        </div>
                    </div>
                    <!--
                legend:{
                    SP:'四平校区',
                    JD:'嘉定校区',
                    active:'当前选择',
                    unarranged:'待安排',
                    arranged:'已安排',
                    multi:'多课程',
                    teacherArranged:'老师已排课'
                },
                    -->
                    <edu-timetable :class-data="otherClasses" style="min-width:800px;" pageName="ARRANGE" :disable-time="disableTime" :saved="arranged" :selected="selected" :actived="activedCell" @cell-click="select" :legend="{
                        'active':$t('arrangement.legend.active'),
                        'saved': $t('arrangement.legend.arranged'),
                        'selected': $t('arrangement.legend.unarranged'),
                        'c1': $t('arrangement.legend.teacherArranged1'),
                        'c1-1': $t('arrangement.legend.teacherArranged2'),
                        'bg1': $t('arrangement.legend.SP'),
                        'bg2': $t('arrangement.legend.JD'),
                        'bgmul': $t('arrangement.legend.multi'),
                    }">
                        <!-- 不显示 但是要用 param-switch 组件加载配置数据 -->
                        <span v-show="false" slot="legend" class="float-right" :title="$t('arrangement.tips.globalState')">
                            {{$t('arrangement.disable9')}}:
                            <param-switch ref="paramSwitch" :code="restrictScope==1?'disable9_1':'disable9'" v-model="disable9"></param-switch>
                        </span>
                    </edu-timetable>
                </div>
                <div style="margin-top:5px;height:30px;">
                    <span class="float-right">
                        <el-button @click="back">{{$t('message.close')}}</el-button>
                        <el-button @click="save()" v-if="detailsFlag" type="primary">{{$t('message.submit')}}</el-button>
                    </span>
                </div>
            </el-container>
            <!-- 更换教师弹出框 -->
            <el-dialog v-if="teacherSwap" width="400px" :title="$t('arrangement.swapTeacher')" :visible.sync="showSwapTeacherDialog" :close-on-click-modal="false" :append-to-body="true">
                <el-form label-position="left" label-width="70px" size="mini">
                    <el-form-item :label="$t('arrangement.teacher')">{{teacherString}}</el-form-item>
                    <el-form-item :label="$t('arrangement.swapTo')">
                        <TeacherSelect v-model="swappedTeacher" multiple></TeacherSelect>
                    </el-form-item>
                </el-form>
                <label style="color:#aaa">{{$t('arrangement.swapTeacherTips')}}</label>
                <span slot="footer" class="dialog-footer">
                    <el-button @click="showSwapTeacherDialog = false">{{$t('message.cancel')}}</el-button>
                    <el-button type="primary" @click="swapTeacher">{{$t('message.submit')}}</el-button>
                </span>
            </el-dialog>
            <!-- 指定教师弹出框 -->
            <el-dialog width="400px" :title="$t('arrangement.allocateTeacher')" :visible.sync="showSelectTeacherDialog" :close-on-click-modal="false" :append-to-body="true">
                <el-form label-position="right" label-width="120px" size="mini">
                    <el-form-item :label="$t('arrangement.teacher')">
                        <teacher-select v-model="selectTeacher" multiple :conditionNotNull="false" :condition="options.teacherSelectCondition" fixed></teacher-select>
                    </el-form-item>
                    <el-form-item :label="$t('arrangement.forAll')">
                        <el-checkbox v-model="options.teacherForAll"></el-checkbox>
                    </el-form-item>
                </el-form>
                <span slot="footer" class="dialog-footer">
                    <el-button @click="showSelectTeacherDialog = false">{{$t('message.cancel')}}</el-button>
                    <el-button type="primary" @click="setTeacher">{{$t('message.submit')}}</el-button>
                </span>
            </el-dialog>
        </div>
        <div v-if="page=='swapteacher'">
            <el-header class="arrange-panel-header" height="50px">
                <div class="class-profiles">
                    <div class="head-text" style="font-size:18px">{{$t('arrangement.swapTeacher')}}</div>
                </div>
                <el-button class="float-right" @click="emitSwapteacher(false)">{{$t('common.btn.back')}}</el-button>
            </el-header>
            <swap-teacher :time-rooms-map="timeRoomsMap" :class-data="classData" @update="teacherUpdate=true" />
        </div>
    </div>
</template>
<script>
import SchoolCalendarApi from "common/src/api/calendars";
import PreArrangeentApi from "common/src/api/course/preArrangeent";
import ManArrangeApi from "common/src/api/course/manArranget";
import { getLessonRelationTimetable } from "common/src/api/coursearrangement/timetable";
import { findSelectList } from "common/src/api/resource/classroom";
import { findTeacherList } from "common/src/api/resource/teachers";
import { updateClassItem } from "common/src/api/schedule/taskInput";
import Occupation from "common/src/api/coursearrangement/arrangeOccupy";
import EduTimetable from "common/src/components/common/EduTimetable";
import SwapTeacher from "common/src/views/course/component/SwapTeacher";
import UTILS from "common/src/utils/utils";
import { dayTimeToString } from "common/src/utils/arrange";
import { getValue } from "common/src/api/commonParam";
import { panelArrange, getDetail, classBorrow } from 'common/src/api/practiceManagement/scheduleSetting';
import commonMixins from '../commonMixins';
import moment from 'moment';
export default {
    name: "ArrangePanel",
    mixins: [commonMixins],
    props: {
        classId: {
            required: true
        },
        detailsFlag: {
            type: Boolean,
            default: true
        },
        arrangementType: {
            default: "manual"
        },
        periodError: {
            // 学时误差
            default: 0,
            type: Number
        },
        periodLimit: {
            // 是否检查学时误差
            default: false,
            type: Boolean
        },
        teacherDisabled: {
            // 是否允许安排老师
            default: false,
            type: Boolean
        },
        teacherLimit: {
            // 是否检查是否安排老师
            default: false,
            type: Boolean
        },
        teacherSwap: {
            // 是否允许更换教师
            default: false,
            type: Boolean
        },
        classroomDisabled: {
            // 是否允许安排教室
            default: false,
            type: Boolean
        },
        classroomLimit: {
            // 是否检查是否安排教室
            default: false,
            type: Boolean
        },
        restrictScope: {
            // 约束检查类型
            default: 0,
            type: Number
        },
        classroomTbd: {
            // 教室待定 to be determined
            default: false,
            type: Boolean
        },
        calendarId: {
            type: Number
        },
        ids: {
            type: String
        },
        objs: {
            type: Object
        }
    },
    components: { EduTimetable, SwapTeacher },
    computed: {
        classProfiles() {
            const data = this.classData;
            let info;
            if (this.arrangementType == "pre") {
                if (data.preArrangeTimes && data.preArrangeTimes.length > 0) {
                    info = data.preArrangeTimes.map(item =>
                        dayTimeToString(
                            item.dayOfWeek,
                            item.timeStart,
                            item.timeEnd
                        )
                    ).reduce((a, b) => a + "," + b);
                } else {
                    info = "";
                }
            } else {
                info = data.arrangeInfo;
            }
            const strs = [info, data.campusI18n];
            return strs.filter(item => !!item).join(" | ");
        },
        dayTimeString() {
            const active = this.activedCell;
            if (active && active.length > 0) {
                return active.map(item =>
                    dayTimeToString(
                        item.dayOfWeek,
                        item.timeStart,
                        item.timeEnd
                    )
                ).reduce((a, b) => a + "," + b);
            }
            return "";
        },
        activeTimeObject() {
            if (this.activeTime) {
                let args = this.activeTime.split("-");
                return {
                    dayOfWeek: args[0],
                    timeStart: args[1],
                    timeEnd: args[2]
                };
            } else {
                return {};
            }
        },
        teachers() {
            return this.classData.teacherList
                ? this.classData.teacherList.map(teacher => {
                    return {
                        code: teacher.teacherCode,
                        name: teacher.teacherName,
                        title: teacher.teacherTitle
                    };
                })
                : [];
        },
        teacherString() {
            return this.teachers.length ? this.teachers.map(t => t.name + "(" + t.code + ")").reduce((a, b) => a + ", " + b) : "";
        },
        notPublicRoom() {
            return this.classData.roomCategory > 1;
        }
    },
    watch: {
        activeTime(val) {
            if (val) {
                this.activeRoom = this.timeRoomsMap[val];
                this.fillActiveRoom();
                let allDeleted = true; // 判断是否整个数组都是deleted
                this.checkedList = this.activeRoom.map(room => {
                    if (!room.isDeleted) {
                        // 如果有任何一个没被删除 置为false
                        allDeleted = false;
                    }
                    return !room.isDeleted;
                });
                if (allDeleted) {
                    // 如果全部删除 就选中全部而不是未删除部分
                    this.checkedList = this.activeRoom.map(room => true);
                }
                this.allChecked = true;
                this.isIndeterminate = false;
            } else {
                this.activeRoom = null;
                this.checkedList = [];
                this.allChecked = false;
                this.isIndeterminate = false;
            }
            this.weekMode = "0";
        },
        disable9(val) {
            if (val) {
                this.disableTime = [];
            } else {
                this.disableTime = [9];
            }
        },
        weekStart(val) {
            if (this.weekEnd < val) this.weekEnd = val;
            // this.selectedList();
        },
        weekEnd(val) {
            if (this.weekStart > val) this.weekStart = val;
            // this.selectedList();
        },
        // selectSpan(newVal, oldVal) {
        //     if (newVal > this.weekHours) {
        //         this.$message({
        //             message: this.$t("arrangement.tips.notGtWeekHour"),
        //             type: "warning",
        //             duration: 1500
        //         });
        //     }
        // },
        showSelectRoomDialog(val) {
            // 如果没有勾选任何行，则默认选择全部
            if (val) {
                let checkList = this.checkedList;
                let flag = true;
                for (let i = 0; i < checkList.length; i++) {
                    if (checkList[i]) {
                        flag = false;
                        break;
                    }
                }
                this.options.roomForAll = flag;
            }
        },
        showSelectTeacherDialog(val) {
            // 如果没有勾选任何行，则默认选择全部
            if (val) {
                let checkList = this.checkedList;
                let flag = true;
                for (let i = 0; i < checkList.length; i++) {
                    if (checkList[i]) {
                        flag = false;
                        break;
                    }
                }
                this.options.teacherForAll = flag;
            }
        },
        checkedList(val) {
            if (val != null && val.length > 0) {
                let firstFlag = false;
                let tempStart = 0;
                let tempEnd = 0;

                // 奇数checkbox勾选数
                let mode1Counter = 0;
                // 偶数checkbox勾选数
                let mode2Counter = 0;
                for (let i = 0; i < this.activeRoom.length; i++) {
                    if (this.activeRoom[i].isDeleted === true) {
                        continue;
                    }

                    if (!firstFlag) {
                        // 设置起始值
                        tempStart = (i + 1) > this.startInfo ? (i + 1) : this.startInfo;
                        firstFlag = true;
                    }

                    // 设置结束值
                    tempEnd = i + 1;
                    (i + 1) % 2 === 1 ? mode1Counter++ : mode2Counter++;
                }

                // 统计周数
                let weeks = tempEnd - tempStart + 1;
                if ((mode1Counter + mode2Counter) == weeks) {
                    this.weekMode = "0"
                } else {
                    if (mode1Counter == 0) {
                        this.weekMode = "2";
                    } else if (mode2Counter == 0) {
                        this.weekMode = "1";
                    } else {
                        this.weekMode = "";
                    }
                }

                this.weekStart = tempStart;
                this.weekEnd = tempEnd;

            } else {
                this.weekStart = 1;
                this.weekEnd = this.calendarData.weekNum;
                this.weekMode = "0";
            }
        }
    },
    mounted() {
        this.getDetails().then((res) => {
            // this.initClassData();
            this.init();
        })
    },
    data() {
        return {
            page: "arrange",
            calendarData:{},
            classData: {
                courseName: '',
                code: '',
                roomLabel: '',
                teacherList: []
            },
            showRoomTable: false,
            showSelectRoomDialog: false,
            showSelectTeacherDialog: false,
            showSwapTeacherDialog: false,
            disable9: false, // 第九节是否排课
            freeArramge: false,
            disableTime: [9],
            options: {},
            allChecked: false,
            isIndeterminate: false,
            checkedList: null,
            selectRoom: null, // 教室选择
            selectTeacher: null,
            swappedTeacher: null,
            activeTime: [],
            activeRoom: [],
            otherClasses: [],
            activedCell: [],
            selected: [],
            arranged: [],
            timeRoomsMap: {},
            selectSpan: 0, // 单次选择长度
            weekHours: 0,
            period: 0,
            arrangedPeriod: 0,
            // remainHours: 4,// 剩余周学时
            availableWeeks: null, // 排课可用周
            weekStart: null, // 开始周
            weekEnd: null, // 结束周
            weekMode: '', // 周次
            roomIds: [], //当前课程占用的教室Id
            occupiedClassroomIds: [],
            teacherUpdate: false, // 如果更新了任课老师
            options: {
                compus: [],
            },
            timeObj: {
              startAt: '',
              endAt: ''
            },
            startInfo: null, // 排课表单上课开始时间
            endInfo: null, // 排课表单上课结束时间
        };
    },
    methods: {
        getDetails() { // 获取排课详情
            return new Promise((resolve, reject) => {
                let jsons = {
                    X_XQ: 'compus'
                }
                let p1 = ManArrangeApi.getClass(this.classId);
                let p2 = getDetail({ id: this.objs.dataId });
                let p3 = this.initOptions(jsons);
                let p4= SchoolCalendarApi.get(this.calendarId);
              Promise.all([p1, p2, p3,p4]).then(res1 => {
                    if (res1[0].data) {
                        this.classData = res1[0].data;
                    }
                    if(res1[3].data){
                        this.calendarData = res1[3].data;
                    }
                    let teacher = [];
                    if (res1[1].data.mainTeacherJobno) {
                        teacher.push({ teacherCode: res1[1].data.mainTeacherJobno, teacherName: res1[1].data.mainTeacherName });
                    }
                    if (res1[1].data.instructorTeacherJobno) {
                        teacher.push({ teacherCode: res1[1].data.instructorTeacherJobno, teacherName: res1[1].data.instructorTeacherName });
                    }
                    this.timeObj.startAt = res1[1].data.courseDateStart;
                    this.timeObj.endAt = res1[1].data.courseDateEnd;
                    this.$set(this.classData, 'startWeek', 1);
                    this.$set(this.classData, 'endWeek', res1[3].data.weekNum);
                    this.$set(this.classData, 'teacherList', teacher);
                    this.$set(this.classData, 'yearTerm', this.objs.yearTerm);
                    resolve(res1);
                })
            });
        },
        init() { // 初始化
            this.initClassData();
            let arrangeTimes = this.getArrangementTimes();
            let arranged = arrangeTimes && arrangeTimes.length ? arrangeTimes.map(a => {
                return {
                    code: this.classData.code,
                    value: a.profile,
                    id: a.id,
                    dayOfWeek: a.dayOfWeek,
                    timeStart: a.timeStart,
                    timeEnd: a.timeEnd
                };
            }) : [];
            let promise1 = getLessonRelationTimetable(this.classId);
            let promise2 = this.getArrangeentApi().getArrangeRoom(this.classId);
            let classroomMap = {};
            Promise.all([promise1, promise2]).then(res => {  // 获取当前教学班排课和相关教学班排课
                this.initOtherClasses(_.concat(res[0].data, arranged));
                let arrangeRooms = res[1].data;
                let map = {}; // 根据time 和 room的 arrangetimeid来组装 time和room 的关系
                arranged.forEach(item => {
                    map[item.id] = [];
                });
                // 获取教室信息
                let roomIds = Array.from(
                    new Set(arrangeRooms.map(a => a.roomId))
                );
                findSelectList({
                    includeIds: roomIds,
                    pageNum_: 1,
                    pageSize_: roomIds.length
                }).then(res => {
                    const dataList = res.data.list;
                    dataList.forEach(item => {
                        classroomMap[item.id] = item;
                    });
                    if (arrangeRooms.length > 0) {
                        this.selectRoom = dataList[0]; // 把第一个教室设为默认教室，排课时默认安排
                    } else {
                        this.selectRoom = null;
                    }
                    let teacherMap = {};
                    this.selectTeacher.forEach(teacher => {
                        teacherMap[teacher.code] = teacher;
                    });
                    arrangeRooms.forEach(item => {
                        if (item.roomId == 0) {
                            item.roomName = this.classData.roomLabel;
                        } else {
                            let classroom = classroomMap[item.roomId];
                            if (classroom) {
                                item.roomName = `${classroom.name}${classroom.towerName ? "(" + classroom.towerName + ")" : ""}`; // 用于显示的教室名
                            } else {
                                item.roomName = null;
                                item.roomId = null;
                            }
                        }
                        // teacherCode 逗号分隔可能有多个
                        let teacherCodes = item.teacherCode ? item.teacherCode.split(",") : [];
                        let teacherList = teacherCodes.map(code => teacherMap[code]).filter(teacher => !!teacher);
                        if (teacherList.length > 0) {
                            item.teachers = teacherList.map(t => t.name + "(" + t.code + ")").reduce((a, b) => a + "," + b);
                            map[item.arrangeTimeId].push(item);
                            item.id = null;
                            item.arrangeTimeId = null;
                        }
                    });
                    let timeRoomsMap = {};
                    arranged.forEach(item => {
                        timeRoomsMap[`${item.dayOfWeek}-${item.timeStart}-${item.timeEnd}`] = map[item.id];
                        // 删除主键外键 防止影响数据提交
                        item.id = null;
                    });
                    this.timeRoomsMap = timeRoomsMap;
                    this.updateArrangedPeriod();
                });
            });
            this.arranged = arranged;
        },
        initClassData() {
            let hours = this.classData.weekHour;
            let startWeek = this.classData.startWeek ? this.classData.startWeek : 1;
            let endWeek = this.classData.endWeek ? this.classData.endWeek : 1;
            let isEdit = false;
            if (this.arrangementType == "pre") {
                if (this.classData.preArrangeFlag && this.classData.preArrangeFlag !== "0") isEdit = true;
            } else {
                if (this.classData.manArrangeFlag !== "0") isEdit = true;
            }

            let teachers = this.classData.teacherList
                ? this.classData.teacherList.map(teacher => {
                    return {
                        code: teacher.teacherCode,
                        name: teacher.teacherName,
                        title: teacher.teacherTitle
                    };
                })
                : [];
            let data = {
                showSelectRoomDialog: false,
                showSelectTeacherDialog: false,
                showSwapTeacherDialog: false,
                disable9: false, // 第九节是否排课
                freeArramge: false,
                disableTime: [9],
                options: {
                    isEdit,
                    roomCondition: {
                        campus: this.classData.campus,
                        type: this.classData.roomType,
                        gtClassNumber: this.classData.number
                    },
                    roomForAll: false,
                    teacherForAll: false,
                    teacherSelectCondition: {
                        codeList: this.classData.teacherList.map(
                            t => t.teacherCode
                        ),
                        pageNum_: 0,
                        pageSize_: 0
                    },
                    timesList: (() => {
                        let arr = [];
                        let max = hours > 6 ? 6 : hours; // 排课时常最大为6 并且不超过周学时
                        for (let i = 0; i < max; i++) {
                            arr.push({ label: i + 1, value: i + 1 });
                        }
                        return arr;
                    })(),
                    classroomList: []
                },
                allChecked: false,
                isIndeterminate: false,
                checkedList: null,
                selectRoom: null,
                selectTeacher: teachers,
                swappedTeacher: [],
                activeTime: null,
                activeRoom: null,
                otherClasses: [],
                activedCell: [],
                selected: [],
                arranged: [],
                timeRoomsMap: {},
                selectSpan: hours >= 2 ? 2 : 1, // 单次选择长度
                weekHours: hours,
                period: this.classData.period,
                arrangedPeriod: 0,
                // remainHours: 4,// 剩余周学时
                availableWeeks: (() => {
                    // 排课可用周
                    let arr = [];
                    for (let i = startWeek; i <= endWeek; i++) {
                        arr.push(i);
                    }
                    return arr;
                })(),
                weekStart: startWeek,
                weekEnd: endWeek,
                weekMode: this.classData.arrangeMode
            };
            for (const key in data) {
                if (data.hasOwnProperty(key)) {
                    this[key] = data[key];
                }
            }
            this.$refs.paramSwitch.getValue();
        },
        initOtherClasses(data) { /*图例c1: '老师已排课',c2: '专业已排课',bg1: '四平校区',bg2: '嘉定校区'  */
            let otherClassData = data.filter(v=> v.timeEnd !== 0 && v.timeStart !== 0);
            let teacherCodes = this.teachers.map(t => t.code);
            const undergraduateLevel = ["1", "5"];
            this.otherClasses = otherClassData.map(other => {
                let legends = [];
                if (other.campus == "1") {
                    legends.push("bg1");
                } else if (other.campus == "3") {
                    legends.push("bg2");
                }
                // 教师code 有交集
                if (
                    other.teacherCodes &&
                    other.teacherCodes.filter(t => teacherCodes.includes(t))
                        .length > 0
                ) {
                    if (undergraduateLevel.indexOf(other.trainingLevel) >= 0) {
                        legends.push("c1");
                    } else {
                        legends.push("c1-1");
                    }
                }
                return {
                    ...other,
                    legends
                };
            });
        },
        getArrangeentApi() { // 接口替换
            return this.arrangementType == "pre" ? PreArrangeentApi : ManArrangeApi;
        },
        getArrangementTimes() { // 接口替换
            return this.arrangementType == "pre" ? this.classData.preArrangeTimes : this.classData.manArrangeTimes;
        },
        hover(day, time, right) {
            let timeStart = this.convertTime(time);
            if (timeStart < 0) {
                return;
            }
            let timeEnd = timeStart - 1 + this.selectSpan;
            let item = {
                dayOfWeek: day,
                timeStart: timeStart,
                timeEnd: timeEnd
            };
            this.selected = [item];
        },
        select(day, time, right) { // 排课
            this.showRoomTable = false;
            let arranged = this.arranged.filter(
                item => item.dayOfWeek == day && item.timeStart == time
            );
            if (right) {
                // 右键点击为删除 不能右键删除已安排课程
                if (arranged.length > 0) {
                    // 右键点击已安排时段
                    this.activedCell = [];
                    this.activeTime = null;
                } else {
                    let deleted = this.selected.filter(
                        item =>
                            item.dayOfWeek == day &&
                            item.timeStart <= time &&
                            item.timeEnd >= time
                    );
                    if (deleted.length > 0) {
                        this.activedCell = [];
                        // this.remainHours+=deleted.map(item=>item.timeEnd-item.timeStart+1).reduce((a,b)=>a+b);
                        this.selected = this.selected.filter(
                            item =>
                                !(
                                    item.dayOfWeek == day &&
                                    item.timeStart <= time &&
                                    item.timeEnd >= time
                                )
                        );
                        deleted.forEach(
                            item => delete this.timeRoomsMap[`${item.dayOfWeek}-${item.timeStart}-${item.timeEnd}`]
                        );
                        this.activeTime = null;
                    }
                }
            } else {
                let repeat = this.selected.filter(
                    item =>
                        item.dayOfWeek == day &&
                        item.timeStart <= time &&
                        item.timeEnd >= time
                );
                // 如果不存在相同时间的选择
                let item;
                if (repeat.length == 0 && arranged.length == 0) {
                    let timeStart = this.convertTime(time);
                    if (timeStart < 0) {
                        this.$message({
                            message: this.$t("arrangement.tips.unableTime", {
                                span: this.selectSpan
                            }),
                            type: "warning",
                            duration: 1500
                        });
                        return;
                    }
                    let timeEnd = timeStart - 1 + this.selectSpan;
                    let arrangedRepeat = this.arranged.filter(
                        item =>
                            item.dayOfWeek == day &&
                            item.timeStart <= timeEnd &&
                            item.timeEnd >= timeStart
                    );
                    let selectedRepeat = this.selected.filter(
                        item =>
                            item.dayOfWeek == day &&
                            item.timeStart <= timeEnd &&
                            item.timeEnd >= timeStart
                    );
                    if (arrangedRepeat.length + selectedRepeat.length > 0) {
                        this.$message({
                            message: this.$t("arrangement.tips.conflict", {
                                timeStart,
                                timeEnd
                            }),
                            type: "warning",
                            duration: 1500
                        });
                        return;
                    }
                    this.activedCell = [];
                    item = {
                        dayOfWeek: day,
                        timeStart: timeStart,
                        timeEnd: timeEnd
                    };
                    this.selected.push(item);
                    this.activeTime = `${item.dayOfWeek}-${item.timeStart}-${item.timeEnd}`;
                    this.timeRoomsMap[`${item.dayOfWeek}-${item.timeStart}-${item.timeEnd}`] = [];
                } else {
                    //点击已选择的时段
                    if (arranged.length > 0) {
                        // 如果是已存储的
                        this.activedCell = [arranged[0]];
                        item = arranged[0];
                    } else {
                        item = repeat[0];
                    }
                    // 切换到指定时段
                    this.activeTime = `${item.dayOfWeek}-${item.timeStart}-${item.timeEnd}`;
                }
            }
        },
        convertTime(timeUnit) { // 检查时间是有相同的
            let timeMapping = {
                2: { 1: 1, 2: 1, 3: 3, 4: 3, 5: 5, 6: 5, 7: 7, 8: 7, 9: 9, 10: 10, 11: this.disable9 ? 11 : 10, 12: this.disable9 ? 11 : -1 },
                3: { 1: 1, 2: 2, 3: 2, 4: 2, 5: 5, 6: 6, 7: 6, 8: 6, 9: 9, 10: 10, 11: 10, 12: 10 },
                4: { 1: 1, 2: 1, 3: 1, 4: 1, 5: 5, 6: 5, 7: 5, 8: 5, 9: 9, 10: 9, 11: 9, 12: 9 },
                5: this.disable9 ? { 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 8, 10: 8, 11: 8, 12: 8 }
                    : {
                        1: 1, 2: 2, 3: 3, 4: 4, 5: 4, 6: 4, 7: 4, 8: 4 // 第九节不可排
                    },
                6: this.disable9
                    ? {
                        1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 7, 9: 7, 10: 7, 11: 7, 12: 7 // 第九节可排课
                    } : {
                        1: 1, 2: 2, 3: 3, 4: 3, 5: 3, 6: 3, 7: 3, 8: 3 // 第九节不可排
                    }
            };
            let map = timeMapping[this.selectSpan];
            if (!map) {
                let max = 12 - this.selectSpan + 1; // 最大不能超过此值
                return timeUnit > max ? max : timeUnit;
            }
            let convertTime = map[timeUnit];
            if (this.disableTime.includes(convertTime)) return -1;
            return convertTime ? convertTime : -1;
        },
        selectWeekMode(val) { // 教室设置 连续周，单周，双周
            if (!val) {
                this.weekMode = "";
            }
            let checkList = [].concat(this.checkedList);//是否删除，用于回显
            const start = this.classData.startWeek;
            let weekStart = this.weekStart - start; // 索引从0开始
            let weekEnd = this.weekEnd - start;
            let isAll = weekEnd - weekStart + 1 == checkList.length; // 判断是否为全部周
            this.selected.map(item => {
                //获取每个选中的时间节次
                let activeTime = `${item.dayOfWeek}-${item.timeStart}-${item.timeEnd}`;
                // 虽然有watch activeTime 但是有可能是不变的值 所以手动更新
                let activeRoom = this.timeRoomsMap[activeTime];
                for (let i = weekStart; i <= weekEnd && i < checkList.length; i++) {
                    // 如果是删除周不选择
                    // if (this.activeRoom[i] && this.activeRoom[i].isDeleted){
                    //   continue;
                    // }
                    let weekNumber = i + start;
                    switch (val) {
                        case "0":
                            checkList[i] = true;
                            activeRoom[i].isDeleted = false;
                            if (isAll) {
                                this.allChecked = true;
                                this.isIndeterminate = false;
                            } else {
                                this.allChecked = false;
                                this.isIndeterminate = true;
                            }
                            break;
                        case "1": // 单周
                            if ((weekNumber & 1) == 1) {
                                checkList[i] = true;
                                activeRoom[i].isDeleted = false;
                            } else {
                                activeRoom[i].isDeleted = true;
                                checkList[i] = false;
                            }
                            this.allChecked = false;
                            this.isIndeterminate = true;
                            break;
                        case "2": //双周
                            if ((weekNumber & 1) == 0) {
                                checkList[i] = true;
                                activeRoom[i].isDeleted = false;
                            } else {
                                checkList[i] = false;
                                activeRoom[i].isDeleted = true;
                            }
                            this.allChecked = false;
                            this.isIndeterminate = true;
                            break;
                    }
                }
            })
            let activeRoom = this.activeRoom;//选中的时间节
            // isIndeterminate: false,
            for (let i = weekStart; i <= weekEnd && i < checkList.length; i++) {
                // 如果是删除周不选择
                // if (this.activeRoom[i] && this.activeRoom[i].isDeleted){
                //   continue;
                // }
                let weekNumber = i + start;
                switch (val) {
                    case "0":
                        checkList[i] = true;
                        activeRoom[i].isDeleted = false;
                        if (isAll) {
                            this.allChecked = true;
                            this.isIndeterminate = false;
                        } else {
                            this.allChecked = false;
                            this.isIndeterminate = true;
                        }
                        break;
                    case "1": // 单周
                        if ((weekNumber & 1) == 1) {
                            checkList[i] = true;
                            activeRoom[i].isDeleted = false;
                        } else {
                            activeRoom[i].isDeleted = true;
                            checkList[i] = false;
                        }
                        this.allChecked = false;
                        this.isIndeterminate = true;
                        break;
                    case "2": //双周
                        if ((weekNumber & 1) == 0) {
                            checkList[i] = true;
                            activeRoom[i].isDeleted = false;
                        } else {
                            checkList[i] = false;
                            activeRoom[i].isDeleted = true;
                        }
                        this.allChecked = false;
                        this.isIndeterminate = true;
                        break;
                }
            }
            this.checkedList = checkList;
            this.updateArrangedPeriod();
        },
        getOccupiedClassroomIds() { // 指定教室
            let termId = this.calendarId;
            if (!termId) {
                console.error("校历学期为空", this.calendarId);
                return;
            }
            let conditionArr = [];
            let roomIds = new Set();
            for (let i = 0; i < this.activedCell.length; i++) {
                const time = this.activedCell[i];
                const condition = {
                    dayOfWeek: time.dayOfWeek,
                    startTime: time.timeStart,
                    endTime: time.timeEnd,
                    weeks: []
                };
                let arrangeRooms = this.timeRoomsMap[`${time.dayOfWeek}-${time.timeStart}-${time.timeEnd}`];
                for (let j = 0; j < arrangeRooms.length; j++) {
                    const room = arrangeRooms[j];
                    if (!room.isDeleted) {
                        condition.weeks.push(room.weekNumber);
                        roomIds.add(room.roomId);
                    }
                }
                conditionArr.push(condition);
            }
            const self = this;
            Occupation.getOccupiedClassroomIds(termId, conditionArr).then(
                res => {
                    let ids = res.data;
                    let thisIds = Array.from(roomIds);
                    // 去除当前课程的排课
                    for (let i = 0; i < thisIds.length; i++) {
                        const thisId = thisIds[i];
                        for (let j = ids.length - 1; j >= 0; j--) {
                            if (ids[j] == thisId) {
                                ids.splice(j, 1);
                                break;
                            }
                        }
                    }
                    self.occupiedClassroomIds = res.data;
                }
            );
        },
        buildList(start, end, mode) { // 选中单周，双周连续周后排列数据
            let list = [];
            let teacherList = this.selectTeacher;
            let teachers = null,
                teacherCode = null;
            let roomId = null;
            let roomName = null;
            if (this.selectRoom && this.selectRoom.id !== -1) {
                roomId = this.selectRoom.id;
                roomName = `${this.selectRoom.name}(${this.selectRoom.towerName})`;
            }
            if (teacherList && teacherList.length) {
                teachers = teacherList
                    .map(t => t.name + "(" + t.code + ")")
                    .reduce((a, b) => a + "," + b);
                teacherCode = teacherList
                    .map(t => t.code)
                    .reduce((a, b) => a + "," + b);
            }
            for (let weekNumber = start; weekNumber <= end; weekNumber++) {
                switch (mode) {
                    case "0":
                        list.push({
                            weekNumber,
                            teachers,
                            teacherCode,
                            roomId,
                            roomName
                        });
                        break;
                    case "1": // 单周
                        if (weekNumber % 2 == 1)
                            list.push({
                                weekNumber,
                                teachers,
                                teacherCode,
                                roomId,
                                roomName
                            });
                        break;
                    case "2": //双周
                        if (weekNumber % 2 == 0)
                            list.push({
                                weekNumber,
                                teachers,
                                teacherCode,
                                roomId,
                                roomName
                            });
                        break;
                }
            }
            return list;
        },
        updateArrangedPeriod() { // 更新
            let weekSelectMax = 28;
            let map = this.timeRoomsMap;
            let weeks = [];
            if (map && JSON.stringify(map) !== '{}') {
                let arr1 = Object.values(map);
                let arr2 = [];
                arr1.map(item => {
                    arr2 = [...arr2, ...item]
                });
                let obj = {};
                weeks = arr2.reduce((cur, next) => {
                    if (!next.hasOwnProperty('isDeleted') || !next.isDeleted) {
                        obj[next.weekNumber] ? "" : obj[next.weekNumber] = true && cur.push(next);
                    }
                    return cur;
                }, [])
            }
            this.arrangedPeriod = weeks.length * this.classData.weekHour;
        },
        // 遍历选中时段
        traverseActive(operation) {
            for (let i = 0; i < this.activedCell.length; i++) {
                const item = this.activedCell[i];
                const arrangeTime = `${item.dayOfWeek}-${item.timeStart}-${item.timeEnd}`;
                const arrangeRooms = this.timeRoomsMap[arrangeTime];
                if (arrangeRooms) {
                    operation(arrangeRooms);
                }
            }
        },
        handleArrange() {
            this.weekStart = this.startInfo;
            this.weekEnd = this.endInfo;
            this.availableWeeks = (() => {
                // 排课可用周
                let arr = [];
                for (let i = this.startInfo; i <= this.endInfo; i++) {
                    arr.push(i);
                }
                return arr;
            })();
            if (!this.showRoomTable) {
                if (this.weekMode == "") {
                  this.weekMode = "0";
                }
                if (this.activeRoom && this.activeRoom.length > 0) {
                    this.selected = [];
                } else if (this.selected.length > 0) {
                    // 如果是关闭状态，且选择了未安排的时间
                    this.arrangeRooms(
                        this.weekStart,
                        this.weekEnd,
                        this.weekMode
                    );
                }
                for (let i = 0; i < this.checkedList.length; i++) {
                    if (!this.activeRoom[i].isDeleted) {
                        this.checkedList[i] = true;
                    }
                }
                this.allChecked = true;
                this.showRoomTable = true;
            } else {
                let availableItem = this.activeRoom.filter(v=> !v.isDeleted); // 可以安排的周数数据
                let arrangeTempData = {};
                let tempData = {};
                this.showRoomTable = false;
                if (this.selected.length == 0) {
                  let temp = this.activeTime.split('-');
                  arrangeTempData.dayOfWeek = temp[0];
                  arrangeTempData.timeStart = temp[1];
                  arrangeTempData.timeEnd = temp[2];
                  tempData = UTILS.clone([arrangeTempData]);
                } else {
                  tempData = UTILS.clone(this.selected);
                }
                tempData.forEach(item => {
                  item.code = this.classData.code;
                  item.roomName = this.activeRoom.length > 0 ?
                  `${availableItem[0].teachers || ''} ${availableItem[0].roomName || ''}`
                  : '';
                  item.value = `[${this.weekStart}-${this.weekEnd}] ${ item.roomName}`;
                  item.weekStart = this.weekStart
                  item.weekEnd = this.weekEnd
                  item.weekMode = this.weekMode
                });
                for (let i = 0; i < tempData.length; i++) {
                  for (let j = this.arranged.length - 1; j >= 0; j--) {
                    if (this.arranged[j].dayOfWeek == tempData[i].dayOfWeek && this.arranged[j].timeStart ==
                      tempData[i].timeStart && this.arranged[j].timeEnd == tempData[i].timeEnd) {
                      this.arranged.splice(j, 1)
                    }
                  }
                }
                for (let n = 0; n < tempData.length; n++) {
                  this.arranged.push(tempData[n]);
                }
                getLessonRelationTimetable(this.classData.id).then(res => {
                  this.initOtherClasses(_.concat(res.data, this.arranged));
                });
                this.selected = [];
            }
        },
        handelWeekMode(weekMode) { },
        arrangeRooms(start, end, mode) {
            for (let i = 0; i < this.selected.length; i++) {
                const selected = this.selected[i];
                const weekMode = mode || "0";
                let rooms = this.buildList(start, end, weekMode);
                if (rooms.length == 0) {
                    this.$message({
                        message: this.$t("arrangement.tips.noChange"),
                        type: "warning"
                    });
                    return;
                }
                this.$set(
                    this.timeRoomsMap,
                    `${selected.dayOfWeek}-${selected.timeStart}-${selected.timeEnd}`,
                    this.buildList(start, end, weekMode)
                );
            }
            this.arranged = this.arranged.concat(this.selected);
            // 切换到第一个时段
            let active = this.selected[0];
            // this.activedCell = [active];
            this.activedCell = [].concat(this.selected);
            this.activeTime = `${active.dayOfWeek}-${active.timeStart}-${active.timeEnd}`;
            // 虽然有watch activeTime 但是有可能是不变的值 所以手动更新
            this.activeRoom = this.timeRoomsMap[this.activeTime];
            this.fillActiveRoom();
            this.checkedList = this.activeRoom.map(a => false);
            this.allChecked = false;
            this.isIndeterminate = false;

            this.updateArrangedPeriod();
            // this.selected = []; // 清空选择列表
        },
        fillActiveRoom() { // 如果周数少于总周数（即 数据来源于后端）
            let weekRooms = this.activeRoom;
            if (weekRooms && weekRooms.length > 0) {
                let filledRooms = [];
                const start = this.classData.startWeek;
                const end = this.classData.endWeek;
                for (let i = 0; i < weekRooms.length; i++) {
                    const weekRoom = weekRooms[i];
                    filledRooms[weekRoom.weekNumber - start] = weekRoom;
                }
                for (let i = 0; i <= end - start; i++) {
                    if (!filledRooms[i]) {
                        filledRooms[i] = {
                            isDeleted: true,
                            weekNumber: start + i,
                            roomName: "",
                            roomId: null,
                            teachers: ""
                        };
                    }
                }
                this.timeRoomsMap[this.activeTime] = filledRooms;
                this.activeRoom = filledRooms;
            }
        },
        unarrange() {
            let active = this.activedCell[0];
            this.arranged = this.arranged.filter(
                item => !(item.dayOfWeek == active.dayOfWeek && item.timeStart == active.timeStart)
            );
            delete this.timeRoomsMap[`${active.dayOfWeek}-${active.timeStart}-${active.timeEnd}`];
            this.activeTime = null;
            this.updateArrangedPeriod();
            this.activedCell = [];
            this.showRoomTable = false;
            for (let i = this.arranged.length - 1; i >= 0; i--) {
              if (this.arranged[i].dayOfWeek == active.dayOfWeek && this.arranged[i].timeStart == active.timeStart &&
                this.arranged[i].timeEnd == active.timeEnd) {
                this.arranged.splice(i, 1)
              }
            }
            getLessonRelationTimetable(this.classData.id).then(res => {
              this.initOtherClasses(_.concat(res.data, this.arranged));
            });
        },
        setRoom(type) { // 1 清除 2 待定 不传值为常规
            if (this.selectRoom.id == -1) {
                type = 1;
            }
            let roomId = null;
            let roomName = null;
            let roomLabel = this.classData.roomLabel;
            if (!type) {
                if (this.notPublicRoom) {
                    roomId = 0;
                    roomName = roomLabel;
                } else if (this.selectRoom && this.selectRoom.id !== -1) { // 清除教室之后selectRoom值为{id:-1}
                  let selectRoomName = this.selectRoom.towerName ? `${this.selectRoom.name}(${this.selectRoom.towerName})` : `${this.selectRoom.name}`;
                  roomId = this.selectRoom.id;
                  roomName = selectRoomName;
                }
            }

            if (this.options.roomForAll) {
                for (let key in this.timeRoomsMap) {
                    this.timeRoomsMap[key].forEach(a => {
                        a.roomId = roomId;
                        a.roomName = roomName;
                    });
                }
                this.options.roomForAll = false;
            } else {
                let modified = false;
                // 遍历找出所有被选中的时段，修改被勾选周次的值
                const start = this.classData.startWeek;
                this.traverseActive(arrangeRooms => {
                    for (let i = 0; i < arrangeRooms.length; i++) {
                        const arrangeRoom = arrangeRooms[i];
                        if (this.checkedList[arrangeRoom.weekNumber - start]) {
                            arrangeRoom.roomId = roomId;
                            arrangeRoom.roomName = roomName;
                            // arrangeRoom.isDeleted = false;
                            modified = true;
                        }
                    }
                });
                if (!modified) {
                    this.$message({
                        type: "warning",
                        message: this.$t("arrangement.tips.noChange")
                    });
                }
            }

            this.showSelectRoomDialog = false;
        },
        setTeacher() {
            let teachers = null;
            let teacherCode = null;
            let teacherList = this.selectTeacher;
            if (teacherList.length) {
                teachers = teacherList
                    .map(t => t.name + "(" + t.code + ")")
                    .reduce((a, b) => a + "," + b);
                teacherCode = teacherList
                    .map(t => t.code)
                    .reduce((a, b) => a + "," + b);
            }
            if (this.options.teacherForAll) {
                for (let key in this.timeRoomsMap) {
                    this.timeRoomsMap[key].forEach(a => {
                        a.teachers = teachers;
                        a.teacherCode = teacherCode;
                    });
                }
                this.options.teacherForAll = false;
            } else {
                let modified = false;
                const start = this.classData.startWeek;
                this.traverseActive(arrangeRooms => {
                    for (let i = 0; i < arrangeRooms.length; i++) {
                        const arrangeRoom = arrangeRooms[i];
                        if (this.checkedList[arrangeRoom.weekNumber - start]) {
                            arrangeRoom.teachers = teachers;
                            arrangeRoom.teacherCode = teacherCode;
                            modified = true;
                        }
                    }
                });
                if (!modified) {
                    this.$message({
                        message: this.$t("arrangement.tips.noChange"),
                        type: "warning"
                    });
                }
            }
            this.showSelectTeacherDialog = false;
        },
        emitSwapteacher(flag) { // 切换更换老师和排课界面 flag == true 则是切换到更换 否则是 切换回来
            if (flag) {
                this.page = "swapteacher";
            } else {
                // 从更换教师切换回来 更新老师筛选条件的值
                this.options.teacherSelectCondition = {
                    codeList: this.classData.teacherList.map(
                        t => t.teacherCode
                    ),
                    pageNum_: 1,
                    pageSize_: 20
                };
                // 更新任课老师的值
                this.selectTeacher = this.classData.teacherList.map(teacher => {
                    return {
                        code: teacher.teacherCode,
                        name: teacher.teacherName,
                        title: teacher.teacherTitle
                    };
                });

                let updateArrange = JSON.parse(JSON.stringify(this.arranged));
                updateArrange.forEach(f=>{
                    let teacher = this.timeRoomsMap[`${f.dayOfWeek}-${f.timeStart}-${f.timeEnd}`]
                    f.value = `[${teacher[0].weekNumber}-${teacher[teacher.length-1].weekNumber}] ${teacher[0].teachers} ${teacher[0].roomIdI18n}`
                })
                // 刷新课表
                if (this.teacherUpdate) {
                    getLessonRelationTimetable(this.classData.id).then(res => {
                        this.initOtherClasses(_.concat(res.data, updateArrange));
                        this.teacherUpdate = false;
                    });
                }
                this.page = "arrange";
            }
            this.showRoomTable = false;
            this.$emit("swapteacher", flag);
        },
        swapTeacher() {  //老的更换教师 代码保留 已经弃用
            const updateTeacherData = {
                id: this.classData.id,
                code: this.classData.code,
                number: this.classData.number,
                teacherList: this.swappedTeacher.map(teacher => {
                    return {
                        teacherCode: teacher.code,
                        teacherName: teacher.name,
                        teacherTitle: teacher.title,
                        teachingClassId: this.classData.id
                    };
                })
            };
            updateClassItem(this.classData.taskId, updateTeacherData).then(
                res => {
                    this.classData.teacherList = updateTeacherData.teacherList;
                    this.options.teacherSelectCondition = {
                        codeList: this.classData.teacherList.map(
                            t => t.teacherCode
                        ),
                        pageNum_: 1,
                        pageSize_: 20
                    };
                    this.selectTeacher = this.swappedTeacher;
                    this.swappedTeacher = [];
                    this.options.teacherForAll = true;
                    this.setTeacher();
                    this.showSwapTeacherDialog = false;
                    // 更换教师后更新冲突课程列表
                    getLessonRelationTimetable(this.classData.id).then(res => {
                        this.initOtherClasses(res.data);
                    });
                }
            );
        },
        allRoomCheck(val) {
            this.selected.map(item => {
                //获取每个选中的时间节次
                let activeTime = `${item.dayOfWeek}-${item.timeStart}-${item.timeEnd}`;
                // 虽然有watch activeTime 但是有可能是不变的值 所以手动更新
                let activeRoom = this.timeRoomsMap[activeTime];
                for (let i = 0; i < this.checkedList.length; i++) {
                    if (val && ((i+1)<this.startInfo || (i+1)>this.endInfo)) {
                      continue;
                    }
                    this.checkedList[i] = val;
                    activeRoom[i].isDeleted = !val;
                }
            })
            for (let i = 0; i < this.checkedList.length; i++) {
                if (val && (i+1)<this.startInfo || (i+1)>this.endInfo) {
                  continue;
                }
                this.checkedList[i] = val;
                this.activeRoom[i].isDeleted = !val;
            }
            this.isIndeterminate = false;
            this.updateArrangedPeriod();
            this.weekMode = "0";
        },
        roomCheck(index) {
            this.allChecked = this.checkedList.reduce((a, b) => a && b);
            this.isIndeterminate =
                !this.allChecked && this.checkedList.reduce((a, b) => a || b);
            this.selected.map(item => {
                //获取每个选中的时间节次
                let activeTime = `${item.dayOfWeek}-${item.timeStart}-${item.timeEnd}`;
                // 虽然有watch activeTime 但是有可能是不变的值 所以手动更新
                let activeRoom = this.timeRoomsMap[activeTime];
                if (this.checkedList[index]) {
                    activeRoom[index].isDeleted = false;
                } else {
                    activeRoom[index].isDeleted = true;
                }
            })
            if (this.checkedList[index]) {
                this.activeRoom[index].isDeleted = false;
            } else {
                this.activeRoom[index].isDeleted = true;
            }
            this.updateArrangedPeriod();
            this.weekMode = "0";
        },
        checkLimit() {
            let fail = msg => {
                this.$message({
                    message: msg,
                    type: "error"
                });
                return false;
            };
            // 去掉学时校验，保留学时不满足要求的确认提醒（4m3系统中，存在大量安排学时不满总学时的情况）
            // if (
            //     this.periodLimit &&
            //     Math.abs(this.arrangedPeriod - this.period) > this.periodError
            // ) {
            //     // 学时不满足要求
            //     return fail(
            //         this.$t("arrangement.tips.hoursError", {
            //             expect: this.period,
            //             actual: this.arrangedPeriod
            //         })
            //     );
            // } else {
            let map = this.timeRoomsMap;
            let notArranged = true;
            for (let key in map) {
                if (key) {
                    let args = key.split("-");
                    let arrangeRooms = map[key];
                    for (let i = 0; i < arrangeRooms.length; i++) {
                        const room = arrangeRooms[i];
                        if (room.isDeleted) {
                            continue;
                        }
                        if (this.teacherLimit) {
                            if (!room.teacherCode)
                                return fail(
                                    this.$t(
                                        "arrangement.tips.teacherUnarrange"
                                    )
                                );
                        }
                        if (this.classroomLimit) {
                            if (!room.roomId)
                                return fail(
                                    this.$t(
                                        "arrangement.tips.roomUnarrange"
                                    )
                                );
                        }
                        notArranged = false;
                    }
                }
            }
            if (notArranged) {
                return fail(this.$t("arrangement.tips.notAnyArrange"));
            }
            return true;
            // }
        },
        //删除指定周
        deleteSpecified() {
            let checkedList = this.checkedList;
            this.traverseActive(arr => {
                for (let i = arr.length - 1; i >= 0; i--) {
                    const arrangeRoom = arr[i];
                    const weekNumber = arrangeRoom.weekNumber - 1;
                    if (checkedList[weekNumber]) {
                        arrangeRoom.isDeleted = true;
                        arrangeRoom.roomId = null;
                    }
                }
            });
            // 设置所有checkbox为false
            let uncheckedAll = [];
            for (let i = 0; i < this.checkedList.length; i++) {
                uncheckedAll.push(false);
            }
            this.checkedList = uncheckedAll;
            this.isIndeterminate = false;
            this.allChecked = false;
            this.weekMode = null;
            this.updateArrangedPeriod();
        },

        // 修改教学班名称
        updateClassName() {
            ManArrangeApi.updateClass({
                id: this.classData.id,
                name: this.classData.name
            }).then(res => {
                this.$message({
                    type: "success",
                    message: this.$t("message.editSuccess")
                });
            });
        },
        back() {
            this.$emit("back");
        },
        // 保存排课数据
        save(ignoreConflict, ignorePeriod) {
            let data = {
                classId: this.ids,
                classCode: this.classData.code,
                times: [],
                rooms: [],
                ignoreConflict: !!ignoreConflict,
                isEdit: this.options.isEdit,
                restrictScope: this.restrictScope, // 约束检查范围（已分本研配置参数，0：本 1：研）
                classroomTbd: this.classroomTbd // 教室待定
            };
            let classDatas = this.classData;
            if (this.selectRoom) {
                classDatas = {
                    compus: this.selectRoom.campusI18n,
                    calssRoom: this.selectRoom.towerName + this.selectRoom.name,
                    calssRoomType: this.selectRoom.type,
                    teachBuilding: this.selectRoom.towerCode
                }
            } else {
                classDatas = {
                    compus: this.classData.campusI18n,
                    calssRoom: this.classData.campusI18n,
                    calssRoomType: this.classData.classType,
                    teachBuilding: this.classData.towerName
                }
            }
            let datas = {
                id: this.ids,
                classId: this.ids,  // 实习班级ID
                subCourseNo: this.classData.code, // 实习班级ID
                zhDay: this.weekMode, // 周次
                segment: this.selectSpan, // 节次
                segmentStart: '', // 开始授课节次
                segmentEnd: '', // 结束授课节次
                teachWeekStart: this.weekStart, // 开始教学周
                compus: classDatas.compus, // 校区
                teachBuilding: classDatas.teachBuilding, // 教学楼
                calssRoom: '', // 教室
                calssRoomType: classDatas.calssRoomType, // 类型
                teacherName: '' // 授课教师
            }
            for (let i = 0; i < this.arranged.length; i++) {
                const arrangeTime = this.arranged[i];
                if(!arrangeTime.value){
                    continue
                }
                if (!arrangeTime.timeNumber) { // 共后端配对time 和room 的UUID
                    arrangeTime.timeNumber = UTILS.uuid();
                    arrangeTime.arrangeMode = '0'; // 后端接口的验证条件，无意义
                    arrangeTime.classId = data.classId; // 后端接口的验证条件，无意义
                    arrangeTime.startAt = parseInt(moment(this.timeObj.startAt).format('x')); // 实践课开始时间
                    arrangeTime.endAt = parseInt(moment(this.timeObj.endAt).format('x')); // 实践课结束时间
                }
                let arrangeRooms = this.timeRoomsMap[`${arrangeTime.dayOfWeek}-${arrangeTime.timeStart}-${arrangeTime.timeEnd}`];
                let hasArrange = false;
                // 如果当前安排数据没有教室或老师信息，给出提示信息不进行安排保存
                let availableItem = arrangeRooms.filter(v=> !v.isDeleted); // 可以安排的周数数据
                let roomNameList = availableItem.filter(v=> v.roomName);
                let teachersList = availableItem.filter(v=> v.teachers);
                if (availableItem.length !== roomNameList.length && availableItem.length !== teachersList.length) {
                  this.$message.error(this.$t('courseConfirmation.tips.notArrangeEnough'));
                  return;
                }
                if (availableItem.length > 0 && (roomNameList.length == 0 || availableItem.length !== roomNameList.length)) {
                  this.$message.error(this.$t('courseConfirmation.tips.notArrangeRoom'));
                  return;
                }
                if (availableItem.length > 0 && (teachersList.length == 0 || availableItem.length !== teachersList.length)) {
                  this.$message.error(this.$t('courseConfirmation.tips.notArrangeTeachers'));
                  return;
                }
                for (let j = 0; j < arrangeRooms.length; j++) {
                    const arrangeRoom = arrangeRooms[j];
                    if (!arrangeRoom.isDeleted) {
                        arrangeRoom.classId = data.classId; // 后端接口的验证条件，无意义
                        arrangeRoom.timeNumber = arrangeTime.timeNumber;
                        data.rooms.push(arrangeRoom);
                        hasArrange = true;
                    }
                }
                if (hasArrange) {
                    data.times.push(arrangeTime);
                }
            }
            this.$set(data, 'courseCode', this.classData.code);
            this.$set(data, 'courseName', this.classData.courseName);
            this.$set(data, 'calendarId', this.classData.yearTerm);
            if (data.rooms.length == 0 || data.times.length == 0) {
              this.$message.error(this.$t('courseConfirmation.tips.notArrangeTips'));
              return;
            }
            // 数据提交
            panelArrange(data).then(response => {
                if (response && response.code !== 200) {
                    this.$message({ message: response.msg, type: 'warning' });
                    return;
                }
                if (response.data.conflict) {
                    let html = response.data.msg
                        .split("||")
                        .reduce(
                            (a, b) => a + "<hr style='margin:3px'>" + b
                        );
                    html = `<div style="font-size:13px">${html}</div>`;
                    if (response.data.hardConflict) {
                        this.$alert(
                            html,
                            this.$t("arrangement.man.checkConflict"),
                            { dangerouslyUseHTMLString: true }
                        );
                    } else {
                        this.$confirm(html, this.$t("arrangement.ignoreConfirm"),
                            {
                                distinguishCancelAndClose: false,
                                dangerouslyUseHTMLString: true,
                                confirmButtonText: this.$t("message.confirm"),
                                cancelButtonText: this.$t("message.cancel")
                            }
                        ).then(() => {
                            this.save(true, true);
                        });
                    }
                } else {
                    classBorrow({ teachingClassId: this.ids });
                    this.$message({ type: "success", message: this.$t("message.editSuccess") });
                    this.showDeptsDialog = false;
                    this.selected = [];
                    let roomIdSet = new Set();
                    this.traverseActive(arrangeRooms => {
                        for (let i = 0; i < arrangeRooms.length; i++) {
                            const arrangeRoom = arrangeRooms[i];
                            if (
                                !arrangeRoom.isDeleted &&
                                arrangeRoom.roomId > 0
                            ) {
                                roomIdSet.add(arrangeRoom.roomId);
                            }
                        }
                    });
                    this.$emit("save");
                    // 保存成功后 即为非首次提交，isEdit应该为true
                    this.options.isEdit = true;
                    this.$emit("back");
                }
                // this.$message({ message: '排课成功', type: 'success' });
            })
        },
        selectWeek() {
            let checkList = [].concat(this.checkedList);
            let weekStart = this.weekStart === 0 ? this.startInfo - 1 : this.weekStart - 1; // 索引从0开始
            // let weekStart = this.weekStart - 1; // 索引从0开始
            let weekEnd = this.weekEnd - 1;
            let isAll = weekEnd - weekStart + 1 == checkList.length; // 判断是否为全部周

            this.selected.map(item => {
                //获取每个选中的时间节次
                let activeTime = `${item.dayOfWeek}-${item.timeStart}-${item.timeEnd}`;
                // 虽然有watch activeTime 但是有可能是不变的值 所以手动更新
                let activeRoom = this.timeRoomsMap[activeTime];

                for (let i = 0; i < checkList.length; i++) {
                    if (i < weekStart || i > weekEnd) {
                        checkList[i] = false;
                        this.allChecked = false;
                        this.isIndeterminate = true;
                        if (activeRoom[i]) {
                            activeRoom[i].isDeleted = true;
                        }
                        continue;
                    }
                    let weekNumber = i + 1;
                    switch (this.weekMode) {
                        case "0":
                            checkList[i] = true;
                            if (activeRoom[i]) {
                                activeRoom[i].isDeleted = false;
                            }
                            if (isAll) {
                                this.allChecked = true;
                                this.isIndeterminate = false;
                            } else {
                                this.allChecked = false;
                                this.isIndeterminate = true;
                            }
                            break;
                        case "1": // 单周
                            if ((weekNumber & 1) == 1) {
                                checkList[i] = true;
                                if (activeRoom[i]) {
                                    activeRoom[i].isDeleted = false;
                                }
                            } else {
                                checkList[i] = false;
                                if (activeRoom[i]) {
                                    activeRoom[i].isDeleted = true;
                                }
                            }
                            this.allChecked = false;
                            this.isIndeterminate = true;
                            break;
                        case "2": //双周
                            if ((weekNumber & 1) == 0) {
                                checkList[i] = true;
                                if (activeRoom[i]) {
                                    activeRoom[i].isDeleted = false;
                                }
                            } else {
                                checkList[i] = false;
                                if (activeRoom[i]) {
                                    activeRoom[i].isDeleted = true;
                                }
                            }
                            this.allChecked = false;
                            this.isIndeterminate = true;
                            break;
                    }
                }
            })
            let activeRoom = this.activeRoom;

            for (let i = 0; i < checkList.length; i++) {
                if (i < weekStart || i > weekEnd) {
                    checkList[i] = false;
                    this.allChecked = false;
                    this.isIndeterminate = true;
                    activeRoom[i].isDeleted = true;
                    continue;
                }

                let weekNumber = i + 1;
                let weekMode = this.weekMode;
                switch (this.weekMode) {
                    case "0": // 连续
                        checkList[i] = true;
                        activeRoom[i].isDeleted = false;
                        if (isAll) {
                            this.allChecked = true;
                            this.isIndeterminate = false;
                        } else {
                            this.allChecked = false;
                            this.isIndeterminate = true;
                        }
                        break;
                    case "1": // 单周
                        if ((weekNumber & 1) == 1) {
                            checkList[i] = true;
                            activeRoom[i].isDeleted = false;
                        } else {
                            checkList[i] = false;
                            activeRoom[i].isDeleted = true;
                        }
                        this.allChecked = false;
                        this.isIndeterminate = true;
                        break;
                    case "2": //双周
                        if ((weekNumber & 1) == 0) {
                            checkList[i] = true;
                            activeRoom[i].isDeleted = false;
                        } else {
                            checkList[i] = false;
                            activeRoom[i].isDeleted = true;
                        }
                        this.allChecked = false;
                        this.isIndeterminate = true;
                        break;
                }
            }
            this.checkedList = checkList;
            this.updateArrangedPeriod();
        },
    }
};
</script>
<style lang="scss">
.arrange-panel {
    .popover {
        position: absolute;
        right: -90px;
        top: 25px;
        width: 550px;
        background: #fff;
        z-index: 999;
        padding: 5px 15px;
        border: 1px solid #dcdfe6;
        .arrange-panel-popover-table {
            border: solid 1px #9c9c9c;
            border-collapse: collapse;
            width: 100%;
            text-align: center;
            color: #454545;
            .head {
                background-color: #ffffff;
                td {
                    height: 30px;
                }
            }
            .body {
                background-color: #f0f2f5;
                max-height: 300px;
                overflow-y: auto;
                td {
                    height: 24px;
                    max-height: 24px;
                    width: 50px;
                    overflow: hidden;
                    text-overflow: ellipsis;
                }
            }
            td {
                font-size: 12px;
                padding: 0;
                border: solid 1px #9c9c9c;
                width: 100px;
                cursor: default;
            }
        }
    }
}
</style>
<style lang="scss" scoped>
.arrange-panel {
    .head-text {
        font-size: 15px;
        color: #000;
    }
    .secondary-text {
        font-size: 13px;
        color: #999;
    }
    .arrange-panel-header {
        // background: #EBEEF5;
        padding: 10px 10px 0;
        margin: 0 0 15px;
        border-bottom: 2px solid #dcdfe6;
        cursor: default;
        .class-profiles {
            float: left;
            width: 35%;
            div {
                padding: 5px 0;
            }
        }
        .period {
            padding: 10px 0;
            width: 80px;
            float: left;
            text-align: center;
            .number {
                font-size: 28px;
            }
        }
    }
    .inline-hidden {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .el-checkbox__inner {
        margin: 0;
    }
    .hours-overview {
        border-collapse: collapse;
        border: solid 1px #9c9c9c;
        text-align: center;
        font-size: 14px;
        td {
            width: 16px;
            height: 16px;
            border: solid 1px #9c9c9c;
        }
    }
    .arrange-tips {
        font-size: 13px;
        color: #454545;
        span {
            margin-right: 8px;
        }
    }
    .value {
        font-weight: 600;
        font-size: 14px;
        padding-left: 5px;
        cursor: default;
    }
    .room-table {
        border: solid 1px #9c9c9c;
        border-collapse: collapse;
        width: 100%;
        text-align: center;
        color: #454545;
        .head {
            background-color: #ffffff;
            td {
                height: 30px;
            }
        }
        .body {
            background-color: #f0f2f5;
            max-height: 300px;
            overflow-y: auto;
            td {
                height: 24px;
                max-height: 24px;
                width: 50px;
                overflow: hidden;
                text-overflow: ellipsis;
            }
        }
        td {
            font-size: 12px;
            padding: 0;
            border: solid 1px #9c9c9c;
            width: 100px;
            cursor: default;
        }
    }
    .deleted {
        color: #aaaaaa;
        background: #dcdfe6;
    }
    .week-mode {
        .el-radio {
            margin-left: 2px;
        }
        .el-radio__label {
            padding-left: 1px;
        }
        .el-radio__inner,
        .el-radio__input {
            margin-right: 1px;
        }
    }
}
</style>
